package service

import (
	"context"
	"fx_swift_boss/api"
	"fx_swift_boss/internal/model"
	"fx_swift_boss/pkg/code"
	"fx_swift_boss/pkg/global"
	"fx_swift_boss/pkg/internalerrors"
	"fx_swift_boss/pkg/logger"
	"fx_swift_boss/pkg/page"
	"github.com/spf13/cast"
	"strings"
)

type IVAInfoSrv interface {
	QueryVACallBackBossList(ctx context.Context, merChantNo string) ([]*api.VAInfoListRes, error)
	QueryVAInfoBossList(ctx context.Context, req *api.VAInfoBossReq) (*page.Collection[*api.VaInfoBossRes], error)
	QueryApplyCode(ctx context.Context, parentCode string) ([]*api.ApplyCodeRes, error)
	GetTradeCodeType(ctx context.Context)
}

type vaInfoSrv struct {
}

func NewVAInfoSrv() IVAInfoSrv {
	return &vaInfoSrv{}
}

// 获取申请子类
func (v vaInfoSrv) QueryApplyCode(ctx context.Context, parentCode string) ([]*api.ApplyCodeRes, error) {
	var (
		err          error
		applyCodeObj []*model.ApplyCode
	)

	if parentCode == "" {
		return []*api.ApplyCodeRes{}, internalerrors.New(code.ErrUnknown, "申请大类不能为空")
	}

	if err = global.GFDB.Ctx(ctx).Schema("fx").Model("ifcgate_apply_code_base").Where("code", parentCode).Scan(&applyCodeObj); err != nil {
		logger.SugarLogger.Error(err)
		return []*api.ApplyCodeRes{}, internalerrors.New(code.ErrUnknown, "查询数据报错")
	}
	if applyCodeObj == nil {
		return []*api.ApplyCodeRes{}, nil
	}

	result := make([]*api.ApplyCodeRes, 0)
	for _, value := range applyCodeObj {
		result = append(result, &api.ApplyCodeRes{
			ParentCode: value.Code,
			DescEn:     value.DescEn,
			DescZh:     value.DescZh,
		})
	}
	return result, err
}

// boss端获取va开户审核列表
func (v vaInfoSrv) QueryVAInfoBossList(ctx context.Context, req *api.VAInfoBossReq) (*page.Collection[*api.VaInfoBossRes], error) {
	var (
		err             error
		resultList      []*model.IFCGateVaInfo
		merChantInfoObj []*model.IFCGateMerChantVAInfo
		total           int
	)
	var merChantNoStr []string
	if len(req.MerName) > 0 {
		mod := global.GFDB.Schema("fx").Model("ifcgate_merchant_va_info")
		//mod.WhereOrLike("mer_name_en", "%"+req.MerName+"%")
		//mod.WhereOrLike("mer_name_cn", "%"+req.MerName+"%")
		mod.Where("mer_name_en like ? or mer_name_cn like ?", "%"+req.MerName+"%", "%"+req.MerName+"%")
		mod.Where("status=?", "SUCC")
		err = mod.Scan(&merChantInfoObj)
		if err != nil {
			logger.SugarLogger.Error(err)
		}
		if merChantInfoObj != nil {
			for _, value := range merChantInfoObj {
				merChantNoStr = append(merChantNoStr, value.MerchantNo)
			}
		} else {
			return &page.Collection[*api.VaInfoBossRes]{}, nil
		}
	}

	collectionDto := &page.Collection[*api.VaInfoBossRes]{}
	collectionDto.Page = req.PageNo
	collectionDto.PageSize = req.PageSize

	mod := global.GFDB.Ctx(ctx).Schema("fx").Model("ifcgate_va_info")
	if len(merChantNoStr) > 0 {
		mod.WhereIn("merchant_no", merChantNoStr)
	}
	if len(req.StartTime) > 0 {
		mod.Where("created_at>=?", req.StartTime+" 00:00:00")
	}
	if len(req.EndTime) > 0 {
		mod.Where("created_at<=?", req.EndTime+"23:59:59")
	}
	if len(req.Status) > 0 {
		mod.Where("status=?", req.Status)
	}

	if len(req.SortFields) > 0 && len(req.SortMethod) > 0 {
		mod.Order(req.SortFields + " " + req.SortMethod)
	}
	mod.Order("created_at desc")
	mod.Limit(int(page.PageToOffset(req.PageNo, req.PageSize)), cast.ToInt(req.PageSize))
	err = mod.ScanAndCount(&resultList, &total, false)
	collectionDto.TotalPage = page.GetTotalPage(req.PageNo, req.PageSize, cast.ToInt64(total))

	if err != nil {
		return nil, internalerrors.New(code.ErrUnknown, "数据查询异常")
	}

	result := make([]*api.VaInfoBossRes, 0)
	for _, value := range resultList {
		busDesDocumentSplit := []string{}
		storeHoldCertify := []string{}
		if value.BusDesDocument != "" {
			busDesDocumentSplit = strings.Split(value.BusDesDocument, ";")
		}
		if value.StoreHoldCertify != "" {
			storeHoldCertify = strings.Split(value.StoreHoldCertify, ";")
		}
		result = append(result, &api.VaInfoBossRes{
			MerOrderNo:       value.MerOrderNo,
			MerChantNo:       value.MerChantNo,
			BizFlow:          value.BizFlow,
			ParentCode:       value.ParentCode,
			ApplyCode:        value.ApplyCode,
			Currency:         value.Currency,
			Area:             value.Area,
			AcctSimpleName:   value.AcctSimpleName,
			BankType:         value.BankType,
			ShopName:         value.ShopName,
			ShopUrl:          value.ShopUrl,
			CollectType:      value.CollectType,
			CollectName:      value.CollectName,
			WebSiteUrl:       value.WebSiteUrl,
			IsSameName:       value.IsSameName,
			CallBackUrl:      value.CallBackUrl,
			BusDesDocument:   busDesDocumentSplit,
			StoreHoldCertify: storeHoldCertify,
			OtherPath:        value.OtherPath,
			Postscript:       value.Postscript,
			CreatedAt:        value.CreatedAt,
			UpdatedAt:        value.UpdatedAt,
			Status:           value.Status,
			Remark:           value.Remark,
		})
	}
	collectionDto.Total = cast.ToInt64(total)
	collectionDto.List = result

	return collectionDto, err
}

// 获取boss端va开户银行信息详情
func (v vaInfoSrv) QueryVACallBackBossList(ctx context.Context, merChantNo string) ([]*api.VAInfoListRes, error) {
	var (
		err           error
		vaInfoListObj []*model.IFCGateVAInfoCallBack
	)

	if err = global.GFDB.Schema("fx").Model("ifcgate_vainfo_call_back").Where("merchant_no=? and status=?", merChantNo, "ON").Scan(&vaInfoListObj); err != nil {
		logger.SugarLogger.Error(err)
		return []*api.VAInfoListRes{}, nil
	}
	if vaInfoListObj == nil {
		return []*api.VAInfoListRes{}, nil
	}

	result := make([]*api.VAInfoListRes, 0)
	for _, value := range vaInfoListObj {
		result = append(result, &api.VAInfoListRes{
			MerOrderNo:  value.MerOrderNo,
			BizFlow:     value.BizFlow,
			CodeName:    value.CodeName,
			BankCode:    value.BankCode,
			Currency:    value.Currency,
			AccountName: value.AccountName,
			AccountNo:   value.AccountNo,
			BankName:    value.BankName,
			BankAddress: value.BankAddress,
			BranchCode:  value.BranchCode,
			CreatedAt:   value.CreatedAt,
			Area:        value.Area,
			CodeValue:   value.CodeValue,
			Remark:      value.Remark,
			Status:      value.Status,
		})
	}
	return result, err
}

// 获取交易编码
func (v vaInfoSrv) GetTradeCodeType(ctx context.Context) {
	var (
		err              error
		tradeCodeTypeObj []*model.IFCGateTradeCodeType
	)
	if err = global.GFDB.Ctx(ctx).Schema("fx").Model("ifcgate_trade_code_type_base").Scan(&tradeCodeTypeObj); err != nil {
		logger.SugarLogger.Error(err)
		return
	}
	for _, value := range tradeCodeTypeObj {
		global.TradeCodeMap[value.Code] = value.Desc
	}
}
